home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d3
/
wrdhplj.arc
/
SOFTREAD.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-04-14
|
18KB
|
516 lines
Program Softread; {version 1.2 July 13, 1988}
{copyright 1988, David K Fibush}
Uses DOS, CRT, Printer;
Type
A3B = Array[1..3] of byte;
A6B = Array[1..6] of byte;
A512B = Array[0..511] of Byte;
A2048B = Array[0..2047] of byte;
S4 = String[4];
S12 = String[12];
A256S8 = Array[0..255] of String[8];
Var
InFile : File of byte; {Input file is bytes}
OutFile : Text; {Output file is text}
FD : A512B; {Font Descriptor}
CD : A2048B; {Character Data can get very large}
EndofFile : Boolean; {End of file reached}
EndofData : Boolean; {No further char data found}
GoodData : Boolean; {Good character data found}
Error : Boolean; {Error in finding data}
Size : real; {Number of bytes read}
WidthData : A256S8; {Width table data}
FirstChar : integer; {First character in width table}
LastChar : integer; {Last character in width table}
Function Exist(TestFile : S12) : boolean; {Test to see if file exists}
Var
Fil : file;
Begin
Assign(Fil, TestFile); {Assign filename to variable}
{$I-} {Turn off error checking}
Reset(Fil); {Attempt to reset file}
{$I+} {Turn on error checking}
Exist := (IOresult = 0); {Exists true if IOresult = 0}
end;
Procedure OpenFiles; {requests filename and opens file}
Var
FileName : String[14];
Begin
EndofFile := false;
Write('Font File '); Readln(FileName);
If NOT Exist(FileName)
Then
Begin
Writeln('The file does not exist');
Halt; {Stops program with error message}
end;
Assign(InFile, FileName); {Assign filename to variable}
Reset(InFile); {Start at begining of file}
End; {OpenFiles}
Function NextByte : Byte; {reads next byte from the file}
Var
OneByte : byte;
Begin
If NOT Eof(InFile) Then
Begin
Read(InFile,OneByte); {reads one byte}
NextByte := OneByte; {assigns value to function}
Size := Size + 1 {increments size}
end {if}
Else
Begin
EndofFile := true; {sets flag}
end; {else}
End; {NextByte}
Function DataSize(TermChar : Char) : Integer;
{With the file pointer positioned at the start of the bytes defining data
size this function will determine the decimal data size by looking for
the terminating character and calculating the value defined by the
interveaning bytes}
Var
DataByte : byte;
ByteNum : Integer; {Current byte number}
NumofBytes : Integer; {Number of bytes in data size}
DecVal, Total, X, Y : Integer;
HexData : A6B;
Begin
ByteNum := 1;
DataByte := NextByte; {read next byte}
{Find terminating character and fill the Hex data array, 7 bytes maximum}
While (Chr(DataByte) <> TermChar) AND (ByteNum < 8) do
Begin
HexData[ByteNum] := DataByte; {assign byte to data array}
DataByte := NextByte; {next byte}
ByteNum := ByteNum + 1; {increment current byte number}
end; {of While}
If ByteNum < 8 then {found correct character}
Begin
Total := 0;
NumofBytes := ByteNum -1; {number of data bytes}
{last was due to reading the TermChar}
For X := NumofBytes downto 1 do {start with least significant}
Begin
DecVal := HexData[X] - 48; {convert Hex to decimal character}
Y := NumofBytes - X;
Case Y of
0 : Total := Total + DecVal;
1 : Total := Total + 10 * DecVal;
2 : Total := Total + 100 * DecVal;
3 : Total := Total + 1000 * DecVal;
4 : Total := Total + 10000 * DecVal;
End {of Case}
End; {of For}
DataSize := Total; {assign value to the function}
end
Else {too many bytes with out finding TermChar}
Begin
DataSize := 0;
Error := true;
end;
End; {of function DataSize}
Procedure FindCmd (CmdStr : S4); {Looks for the command string}
{returns error if not found}
Var
NewStr : String[4]; {String being read}
Counter : Integer;
CmdLen : Integer; {Calculated length of command}
ReadByte : Byte;
Begin
Counter := 0;
ReadByte := NextByte;
While (ReadByte <> 27) AND (Counter < 8) do {Look for escape, try 7 bits}
Begin
ReadByte := NextByte;
Counter := Counter + 1;
end;
If Counter < 8 {Escape, 1B hex, 27 decimal, found}
Then
Begin
CmdLen := Length(CmdStr);
NewStr := '';
For Counter := 1 to CmdLen do NewStr := NewStr + Chr(NextByte);
If NewStr <> CmdStr then Error := true {Error, wrong command}
end
Else Error := true; {Error, escape not found}
end;
Function FDW(FirstByte : integer) : integer; {calc word value of 2 FD bytes}
Begin
FDW := (256 * FD[FirstByte]) + FD[FirstByte + 1];
End;
Function CDW(FirstByte : integer) : integer; {calc word value of 2 CD bytes}
Begin
CDW := (256 * CD[FirstByte]) + CD[FirstByte + 1];
End;
Procedure Descriptor; {Display font descriptor info}
Var
ReadByte : Byte;
Counter : Integer;
DecFD : Integer; {decimal value of font desc length}
Temp : String[20];
Term, Field : String[4]; {symbol set terminating char, field}
Ss : integer; {sym set value}
Calc : real;
Begin
FindCmd(')s'); {Look for Font Descriptor command}
If Error
then
begin
writeln('Font Descriptor command not found');
Halt; {Stops program with error message}
end; {if}
DecFD := DataSize('W'); {Find Font Descriptor data size}
If NOT Error then
Begin
Writeln('Font Descriptor Length ',DecFD,' bytes');
end
Else
Begin
Writeln('Font Descriptor length not found');
Halt; {Stops program with error message}
end;
For Counter := 0 to (DecFD - 1) do {Fill font descriptor array}
FD[Counter] := NextByte;
{Process and display each byte or word of the font descriptor}
Writeln('Font Descriptor Size ',FDW(0));
Case FD[3] of
0 : Temp := '7-bit';
1 : Temp := '8-bit';
2 : Temp := 'PC-8';
else Temp := 'Unknown'
end; {case}
Writeln('Font Type ',Temp);
Writeln('Baseline Distance ',FDW(6),' dots');
Writeln('Cell Width ',FDW(8),' dots');
Writeln('Cell Height ',FDW(10),' dots');
Case FD[12] of
0 : Temp := 'Portrait';
1 : Temp := 'Landscape';
else Temp := 'Unknown';
end;
Writeln('Orientation ',Temp);
Case FD[13] of
0 : Temp := 'Fixed';
1 : Temp := 'Proportional';
else Temp := 'Unknown';
end;
Writeln('Spacing ',Temp);
Ss := FDW(14);
Case Ss of
1 : Temp := 'HP Math-7';
2 : Temp := 'HP Line Draw';
269 : Temp := 'HP Math-8';
21 : Temp := 'ISO 6 ASCII';
53 : Temp := 'HP Legal';
277 : Temp := 'HP Roman-8';
341 : Temp := 'PC-8';
373 : Temp := 'PC-8 D/N';
501 : Temp := 'HP Pi Font';
else Temp := 'Not Listed';
end;
Term := Chr(Ss mod 32 + 64);
Str(SS div 32,Field);
Writeln('Symbol Set ',Temp,' PCL:',Field,Term);
If FD[13] = 0 then {Only show pitch for fixed-spacing}
Begin
Calc := 300/(FDW(16)/4);
Writeln('Pitch ',FDW(16),' ¼dots, ',Calc:4:2,' ch/in');
end
Else
Writeln('Pitch ',FDW(16),' ¼dots');
Calc := ((FDW(18)/4)/300)*72;
Writeln('Height ',FDW(18),' ¼dots, ',Calc:4:2,' points');
Case FD[23] of
0 : Temp := 'Upright';
1 : Temp := 'Italic';
else Temp := 'Unknown';
end;
Writeln('Style ',Temp);
Case FD[24] of
0 : Temp := 'Normal';
3 : Temp := 'Bold';
-7..-1, 2, 4..7 : Temp := '(0=normal, 3=bold)';
else Temp := 'Unknown, weights are -7 to +7';
end;
Writeln('Stroke Weight ',FD[24],' ',Temp);
Case FD[25] of
0 : Temp := 'Line Printer';
3 : Temp := 'Courier';
4 : Temp := 'Helvetica';
5 : Temp := 'Times Roman';
6 : Temp := 'Letter Gothic';
8 : Temp := 'Prestige';
11 : Temp := 'Presentations';
17 : Temp := 'Optima';
18 : Temp := 'Garamond';
19 : Temp := 'Cooper Black';
20 : Temp := 'Coronet Bold';
21 : Temp := 'Broadway';
22 : Temp := 'Bauer Bodoni Black Condensed';
23 : Temp := 'Century Schoolbook';
24 : Temp := 'University Roman';
else Temp := 'Unknown';
end;
Writeln('Typeface ',Temp);
{Bytes 26 through 47 are not very interesting}
Temp := '';
For Counter := 48 to 63 {Font name area of descriptor}
do Temp := Temp + chr(FD[counter]);
Writeln('Font Name ',Temp);
If DecFD > 63 then {Display additional info, if any}
Begin
Write('Additional information ');
For Counter := 64 to (DecFD - 1) do {Show "normal" characters only}
If (FD[counter] > 31) AND (FD[counter] < 126)
then Write(chr(FD[counter]));
end;
Writeln;
End; {Descriptor}
Procedure Characters;
Var
ReadByte : Byte;
Counter : Integer;
DecCD : Integer; {DecCD = decimal value of char desc length}
Temp, S : String[20];
Calc : real;
CharStr : char; {the character being described}
CharVal : integer; {the ASCII value of the character}
TChar : char; {Terminating character of the command}
CodeStr : String[3]; {Character string of the decimal ASCII for CharStr}
Procedure CharCode; {sub-procedure of Procedure Characters}
{With the file pointer positioned at the start of the bytes defining the
character code this procedure will determine the character CharSt and
the code CodeStr by looking for the terminating character and processing
the interveaning bytes. This is similar to Function DataSize}
Var
DataByte : byte;
ByteNum, NumofBytes, DecVal, Total, X, Y : Integer;
HexData : A6B;
Begin
ByteNum := 1;
DataByte := NextByte;
{Find terminating character and fill the Hex data array}
While (Chr(DataByte) <> TChar) AND (ByteNum < 5) do
Begin
HexData[ByteNum] := DataByte;
DataByte := NextByte;
ByteNum := ByteNum + 1;
end; {of While}
If ByteNum < 5 then {found correct character}
Begin
Total := 0;
NumofBytes := ByteNum -1; {number of data bytes}
{last was due to reading the TermChar}
For X := NumofBytes downto 1 do {start with least signigicant}
Begin
DecVal := HexData[X] - 48; {convert Hex to decimal character}
Y := NumofBytes - X;
Case Y of
0 : Total := Total + DecVal;
1 : Total := Total + 10 * DecVal;
2 : Total := Total + 100 * DecVal;
End {of Case}
End; {of For}
CharVal := Total; {assign ASCII value to variable}
CharStr := chr(Total); {assign character to variable}
CodeStr := '';
For X := 1 to NumofBytes do {assign string to variable}
CodeStr := CodeStr + chr(HexData[X]);
end
Else Error := true; {too many bytes with out finding TermChar}
End; {of Procedure CharCode}
Begin {Actual start of Procedure Characters}
FindCmd('*c'); {Look for Character Code command}
If Error
then
If GoodData {there was good stuff once}
then EndofFile := true {no more good stuff, must be endoffile}
else {no good stuff first time, stop prog}
begin
writeln('Character Code command not found');
Halt; {Stops program with error message}
end
else GoodData := true; {At least one char descriptor found}
If NOT EndofFile then begin {loop around for end of file}
TChar := 'E'; {assign terminating character}
CharCode; {Find Character Code}
If NOT Error then
Begin
{ Writeln('Character Code =',CharStr,' Character is ',CodeStr);}
end
Else
Begin
Writeln('Character Code not found');
Halt;
end;
FindCmd('(s'); {Look for Character Descriptor command}
If Error
then
begin
writeln('Character Descriptor command not found');
Halt; {Stops program with error message}
end;
DecCD := DataSize('W'); {Find Character Descriptor data size}
If NOT Error then
Begin
{ Writeln('Character Descriptor Length ',DecCD,' bytes');}
end
Else
Begin
Writeln('Character Descriptor length not found');
Halt; {Stops program with error message}
end;
For Counter := 0 to 15
do CD[Counter] := NextByte; {read char description}
If CharVal < FirstChar then FirstChar := CharVal; {track first char}
If CharVal > LastChar then LastChar := CharVal; {track last char}
Calc := Int(CDW(14)/4); {calculate width in dots}
Str(CharVal,S); {change char value to a string}
Temp := S + ':'; {start building temp}
Str(Calc:1:0,S); {change calc value to a string}
Temp := Temp + S; {finish building string}
WidthData[CharVal] := Temp; {put string in width data array}
GotoXY(30,23); {print on CRT to keep user happy}
Write(CharStr:3,' ',Temp:8);
For Counter := 16 to (DecCD -1)
do ReadByte := NextByte; {eat data bytes}
end; {of loop around for end of file}
End; {Procedure Characters}
Function BinY : boolean; {inputs Y/N requiring a Y or y input to give true}
var {anything else returns false}
Inchar : char;
begin
Inchar := Readkey;
If (Inchar = 'y') or (Inchar = 'Y') then
BinY := true
Else
BinY := false;
end;
Procedure WidthTable;
Var
Response : boolean;
FileName : S12;
Counter, X, Y : integer;
Calc : real;
Begin
Writeln;
Writeln('Character spacing is variable.'); {if variable}
Write('Would you like write a width table (Y/N)? '); {ask about table}
Response := false;
Response := BinY;
Writeln;
If Response then
Begin
Write('Output File? '); {Yes response, open file}
Readln(FileName);
Assign(OutFile, FileName);
Rewrite(OutFile); {will over write file of same name}
FirstChar := 255; {set first/last chars at extreme}
LastChar := 0; {note: this feature is not used
the table includes all characters}
For Counter := 0 to 255 do WidthData[Counter] := ''; {clear array}
While NOT EndofFile do Characters; {get data on each char}
Calc := Round(((FDW(18)/4)/300)*144); {calc font size in ½points}
Writeln(Outfile,'FontSize:',Calc:1:0,' chFirst:', {1st line of}
'1',' chLast:','255'); {table}
X := 0;
Y := Round(Calc/2 + 1); {spaces and undefined characters}
For Counter := 1 to 255 do {are 1/2 height + 1}
Begin
If WidthData[Counter] <> '' then
Write(Outfile,WidthData[Counter]:8)
else Write(Outfile,Counter:5,':',Y:1);
Inc(X);
If X = 8 then {8 columns}
Begin
X := 0;
Writeln(OutFile) {next line}
end;
End;
Writeln(Outfile);
Close(OutFile);
end;
End; {Procedure WidthTable}
Begin
ClrScr;
Error := false;
EndofFile := false;
GoodData := false;
Openfiles;
Size := 0.0;
Descriptor;
If FD[13] = 1 then {only ask about width table if variable spaced}
WidthTable;
Close(InFile);
END.